#ifndef _MACRO_H_
#define _MACRO_H_

#include <type_traits>
#include <variant>

namespace analyzer
{

#define APPLY_DEPENDING_ON_BITNESS(function, bitness, ...)                                                  \
    [&](auto&&... args)                                                                                     \
    {                                                                                                       \
        using T = decltype(function<x86 __VA_OPT__(, ) __VA_ARGS__>(args...));                              \
        using U = decltype(function<x64 __VA_OPT__(, ) __VA_ARGS__>(args...));                              \
        using Result = std::conditional_t<std::is_same_v<T, U>, T, std::variant<T, U>>;                     \
        switch (bitness)                                                                                    \
        {                                                                                                   \
        case x86:                                                                                           \
            return Result(function<x86 __VA_OPT__(, ) __VA_ARGS__>(std::forward<decltype(args)>(args)...)); \
        case x64:                                                                                           \
            return Result(function<x64 __VA_OPT__(, ) __VA_ARGS__>(std::forward<decltype(args)>(args)...)); \
        default:                                                                                            \
            throw std::runtime_error("unexpected bitness");                                                 \
        }                                                                                                   \
    }
} // namespace analyzer

#endif
